?><?
define("fetch_default",0);
define("fetch_need_data",-1);
define("fetch_progress",1);

class entity{

	var $entity	=false;
	var $items	=array();
	var $handle	=false;
	var $key_fields	=false;
	var $index	=0;
	var $debug	=false;
	var $walking	=fetch_default;

	function __construct($handle){
		if(is_a($handle,"database")){
			$this->handle=$handle->handle;
		}else{
			$this->handle=$handle;
		}
	}


	private function _execute($sql){
		if($this->debug===true){
			echo $sql."<br />";
		}
		$r=mysql_query($sql,$this->handle);
		if(!$r){
			throw new Exception(mysql_error($this->handle)."<br />at query:".$sql);
		}
		return $r;
	}

	private function _iexecute($sql){
		if($this->_execute($sql)){
			return mysql_insert_id();
		}
		return false;
	}

	function entity(){
		return $this->entity;
	}

	private function _where($query){
		if(is_array($query)){
			$template=array_shift($query);
			$template=str_replace(array("?"),$this->quote($query),$template);
			$where=$template;
		}else{
			$where=$query;
		}
		return $where;
	}
	private function _fields($fields){
		if(is_array($fields)){
			$fields=implode(',',$fields);
		}
		return $fields;
	}

	function get($query,$fields="*"){
		if($this->walking==fetch_need_data||$this->walking==fetch_default){
			$this->items=array();
			$res=$this->_execute("select ".
				$this->_fields($fields).
					" from ".$this->entity().
					" where ".$this->_where($query));
			while($row=mysql_fetch_array($res)){
				$item=new entity_item();
				$item->load($row);
				$this->items[]=$item;
			}
			if($this->walking==fetch_need_data){
				$this->walking=fetch_in_progress;
			}
			return $this;
		}else{
			return $this->walk();
		}
	}

	function each(){
		$this->walking=fetch_need_data;
	}
	
	function insert($data){
		$keys="(".implode(",",array_keys($data)).") ";
		$values="values (".implode(",",$this->quote(array_values($data))).")";
		return $this->_iexecute(
			"insert into ".$this->entity()." ".$keys." ".$values
		);
	}
	
	function update($id,$data){
		$values="";
		foreach($data as $key=>$val){
			$values.=($values?", ":"")."$key=".$this->quote($val);
		}
		$this->_execute("update ".$this->entity(). " set ".$values." where ".$this->key_fields."=".$this->quote($id));
	}

	function quote($values){
		if(is_array($values)){
			foreach($values as $key=>$value){
				$values[$key]="'".addslashes($value)."'";
			}
		}else{
			$values="'".addslashes($values)."'";
		}
		return $values;
	}

	function exists($id){
		$res=$this->_execute("select count(*) from ".$this->entity()." where {$this->key_fields}=".$this->quote($id));
		$row=$this->next();
		return $row[0]>0?true:false;
	}

	function next($res){
		return mysql_fetch_array($res);
	}

	function walk(){
		if($this->index>count($this->items)){
			$this->index=0;
			$this->walking=false;
			return false;
		}else{
			return $this->items[$this->index++];
		}
	}

	function d($m=false){
		if($m!==false){
			?><pre><?var_dump($m);?></pre><?die();
		}else{
			$this->debug=true;
		}
	}
}

class entity_item{

	function load($data){
		foreach($data as $key=>$value){
			$this->{$key}=$value;
		}
	}
}

class database{
	var $handle=false;

	function __construct($host,$user=false,$pass=false,$database=false){
		if($user===false&&$pass===false&&$database===false){
			$this->handle=$host;
		}else{
			$this->handle=mysql_connect($host,$user,$pass);
			mysql_select_db($database,$this->handle);
		}
		return $this->handle;
	}
}
